/**
* Copyright (C) 2018-2020
* All rights reserved, Designed By www.yixiang.co
* 注意：
* 本软件为www.yixiang.co开发研制，未经购买不得使用
* 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
* 一经发现盗用、分享等行为，将追究法律责任，后果自负
*/
package co.yixiang.modules.auction.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import co.yixiang.api.ApiResult;
import co.yixiang.api.YshopException;
import co.yixiang.common.service.impl.BaseServiceImpl;
import co.yixiang.common.utils.QueryHelpPlus;
import co.yixiang.constant.ShopConstants;
import co.yixiang.domain.BaseDomain;
import co.yixiang.dozer.service.IGenerator;
import co.yixiang.enums.AuctionOrderEnum;
import co.yixiang.enums.BillDetailEnum;
import co.yixiang.enums.BillEnum;
import co.yixiang.modules.auction.domain.*;
import co.yixiang.modules.auction.service.*;
import co.yixiang.modules.auction.service.dto.*;
import co.yixiang.modules.auction.service.mapper.YxAuctionConfigMapper;
import co.yixiang.modules.auction.service.mapper.YxAuctionOrderMapper;
import co.yixiang.modules.auction.service.mapper.YxAuctionRecordMapper;
import co.yixiang.modules.commom.domain.YxAppdict;
import co.yixiang.modules.commom.service.YxAppdictService;
import co.yixiang.modules.delay.DelayOrderQueueManager;
import co.yixiang.modules.delay.DelayOrderWorker;
import co.yixiang.modules.pay.AppPayService;
import co.yixiang.modules.user.domain.*;
import co.yixiang.modules.user.service.YxUserBankService;
import co.yixiang.modules.user.service.YxUserBillService;
import co.yixiang.modules.user.service.YxUserService;
import co.yixiang.modules.user.service.YxUserinfoService;
import co.yixiang.modules.user.service.mapper.*;
import co.yixiang.utils.FileUtil;
import co.yixiang.utils.RandonOrderNoUtil;
import co.yixiang.utils.RedisUtils;
import co.yixiang.utils.RegaxTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;


/**
* @author yhh
* @date 2020-09-21
*/
@Service
@AllArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
@Slf4j
public class YxAuctionOrderServiceImpl extends BaseServiceImpl<YxAuctionOrderMapper, YxAuctionOrder> implements YxAuctionOrderService {

    private final IGenerator generator;
    private final RedisUtils redisUtil;
    private final YxUserinfoService yxUserinfoService;
    private final YxAuctionRecordMapper yxAuctionRecordMapper;
    private final YxAuctionConfigMapper yxAuctionConfigMapper;
    private final YxAppdictService yxAppdictService;
    private final YxUserBillService yxUserBillService;
    private final YxUserService userService;
    private final YxUserBankService userBankService;
    private final YxUserAddressMapper yxUserAddressMapper;
    private final UserMapper userMapper;
    private final YxAuthenticationMapper yxAuthenticationMapper;
    private final YxAuctionProductService yxAuctionProductService;
    private final YxTerracePayInfoService terracePayInfoService;
    private final YxAuctionTakeDeliveryService auctionTakeDeliveryService;
    private final YxAuctionLevelService auctionLevelService;
    private final RedisTemplate redisTemplate;


    @Override
    public Map<String, Object> queryAll(YxAuctionOrderQueryCriteria criteria, Pageable pageable) {
        getPage(pageable);
        PageInfo<YxAuctionOrder> page = new PageInfo<>(queryAll(criteria));
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content", generator.convert(page.getList(), YxAuctionOrderDto.class));
        map.put("totalElements", page.getTotal());
        return map;
    }


    @Override
    public List<YxAuctionOrder> queryAll(YxAuctionOrderQueryCriteria criteria){
        return baseMapper.selectList(QueryHelpPlus.getPredicate(YxAuctionOrder.class, criteria));
    }


    @Override
    public void download(List<YxAuctionOrderDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (YxAuctionOrderDto yxAuctionOrder : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("拍卖id", yxAuctionOrder.getAuctionRecordId());
            map.put("状态0待付款1已上传凭证待确定2待操作3历史订单", yxAuctionOrder.getStatus());
            map.put(" createTime",  yxAuctionOrder.getCreateTime());
            map.put("订单号", yxAuctionOrder.getOrderId());
            map.put("用户id", yxAuctionOrder.getUserId());
            map.put(" userPhone",  yxAuctionOrder.getUserPhone());
            map.put(" userName",  yxAuctionOrder.getUserName());
            map.put(" userAddress",  yxAuctionOrder.getUserAddress());
            map.put(" price",  yxAuctionOrder.getPrice());
            map.put(" payTime",  yxAuctionOrder.getPayTime());
            map.put("支付方式1支付宝2微信3余额4银联", yxAuctionOrder.getPayType());
            map.put(" updateTime",  yxAuctionOrder.getUpdateTime());
            map.put("0未作处理1加入抢拍2收货", yxAuctionOrder.getReceiveType());
            map.put("抢拍手续费", yxAuctionOrder.getServiceMoney());
            map.put("是否支付手续费0否1是", yxAuctionOrder.getIsPayService());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public ApiResult seckillRecord(Long uid, long id) {
        YxUser yxUser=userMapper.selectById(uid);
        //抢拍记录
        YxAuctionRecord yxAuctionRecord=yxAuctionRecordMapper.selectById(id);
        Optional.ofNullable(yxAuctionRecord).orElseThrow(()-> new YshopException("抢拍商品不存在"));
        //认证信息
        YxAuthentication yxAuthentication=yxAuthenticationMapper.selectByUid(uid);
        if(null ==yxAuthentication || 1 !=yxAuthentication.getStatus()) return ApiResult.fail(304 , "请先认证才可参与抢拍");
        //收货地址
        Integer addressCount = yxUserAddressMapper.selectCount(new QueryWrapper<YxUserAddress>().lambda()
                .eq(YxUserAddress::getUid, uid));
        if (addressCount == 0) throw new YshopException("未添加地址");
        //抢拍时间
        YxAuctionConfig yxAuctionConfig = yxAuctionConfigMapper.selectById(yxAuctionRecord.getTimeId());
        Optional.ofNullable(yxAuctionConfig).orElseThrow(()-> new YshopException("抢拍时间有误"));
        //权限
        YxAuctionLevel auctionLevel = auctionLevelService.getOne(new LambdaQueryWrapper<YxAuctionLevel>().eq(YxAuctionLevel::getLevel,yxUser.getHighestLevel()));
        //判断提前进场
        thinkTime(yxAuctionConfig.getStartTime() , yxAuctionConfig.getEndTime() , auctionLevel.getAdvanceTime() , yxUser.getAfterTime() , uid);
        //当抢拍开始时 记录用户
        Integer integer = baseMapper.selectUserLog(uid);
        if(integer == 0) baseMapper.addUserLog(uid);

        //当天的额度
//        BigDecimal sumPrice = this.baseMapper.selectTodayPriceByUid(uid);
//        sumPrice = sumPrice.add(yxAuctionRecord.getPrice());
//        BigDecimal add = auctionLevel.getBidAmount().add(yxUser.getAuctionAmount());
//        if(add.compareTo(sumPrice) == -1) throw new YshopException("您当前拍卖超出当前会员等级额度");
        Integer robAuction = this.baseMapper.selectTodayCountByUid1(uid) + 1;
        Integer ableAuctionCount = yxUser.getAuctionOrders() + 2 ;
        if (robAuction > ableAuctionCount) throw new YshopException("当前超过抢拍次数");

        if (1 == yxAuctionRecord.getIsBuy()) return ApiResult.fail(305 , "已被抢完");
        if (null !=yxAuctionRecord.getUserId() && uid.longValue() == yxAuctionRecord.getUserId().longValue()) throw new YshopException("自己无法抢拍自己的卖单");
        //支付信息
        YxUserinfo yxUserinfo = yxUserinfoService.selectByUserId(yxUser.getUid());
        /*if(0==yxUserinfo.getBindWx()) throw new YshopException("请先绑定微信账号");
        if(0==yxUserinfo.getBindZfb()) throw new YshopException("请先绑定支付宝账号");*/
        if(0 == yxUserinfo.getBindBank()) throw new YshopException("请先绑定银行账户");
        //给商品上锁
        boolean lock = lock("paimai"+yxAuctionRecord.getId(),1,60);
        if(!lock){
            return ApiResult.fail(30 , "已被抢完");
        }

        //给用户金额上锁
        boolean lockUserPrice = lock("UserPrice"+yxUser.getUid(),1,15);
        if (!lockUserPrice){
            //删除拍卖锁
            redisUtil.delete("lockpaimai"+yxAuctionRecord.getId());
            throw new YshopException("您上一笔抢拍订单未支付完毕，请重试");
        }
        //获取用户金额
        BigDecimal nowPrice = new BigDecimal(String.valueOf(redisUtil.get("UserPrice" + yxUser.getUid())));
        /*if (nowPrice.compareTo(new BigDecimal("200")) == -1){
            //删除拍卖锁
            redisUtil.delete("lockpaimai"+yxAuctionRecord.getId());
            //删除用户金额锁
            redisUtil.delete("lockUserPrice"+yxUser.getUid());
            throw new YshopException("抢拍手续费必须大于200");
        }*/
        if(nowPrice.compareTo(yxAuctionRecord.getServiceCharge()) == -1) {
            //删除拍卖锁
            redisUtil.delete("lockpaimai"+yxAuctionRecord.getId());
            //删除用户金额锁
            redisUtil.delete("lockUserPrice"+yxUser.getUid());
            return ApiResult.fail(306 , "手续费不足!");
        }
        BigDecimal balance = nowPrice.subtract(yxAuctionRecord.getServiceCharge()).setScale(2, BigDecimal.ROUND_HALF_UP);
        //扣除余额
        redisUtil.set("UserPrice"+yxUser.getUid() , balance);

        //TB流水入库
        YxUserBill userBill = YxUserBill.builder()
                .uid(yxUser.getUid())
                .title("手续费支付")
                .linkId(yxAuctionRecord.getId().toString())
                .category(BillDetailEnum.CATEGORY_1.getValue())
                .type(BillDetailEnum.TYPE_11.getValue())
                .number(yxAuctionRecord.getServiceCharge())
                .balance(balance)
                .mark("手续费支付")
                .status(BillEnum.STATUS_1.getValue())
                .payType(3)
                .orderNo("cashPledge"+ RandonOrderNoUtil.getOrderIdByTime())
                .pm(BillEnum.PM_0.getValue())
                .build();
        yxUserBillService.save(userBill);

        //塞入扣除redis数据 2秒后修改用户余额
        redisUtil.set(yxUser.getUid()+"deduct"+balance,yxUser.getUid()+"deduct"+balance, 2);
        //删除锁
        redisUtil.delete("lockUserPrice"+yxUser.getUid());

        //修改状态为已卖
        yxAuctionRecord.setIsBuy(1);
        yxAuctionRecordMapper.updateById(yxAuctionRecord);
        delKey(uid , yxAuctionRecord.getServiceCharge() , BigDecimal.ZERO , yxAuctionRecord.getPrice() , yxAuctionRecord.getId());

        //返回
        Map<String, Object> map = new HashMap<>();
        map.put("yxAuctionRecordId", yxAuctionRecord.getId());
        map.put("yxAuctionOrderId", "");
        map.put("price", yxAuctionRecord.getPrice());
        map.put("times", "");

        return ApiResult.ok(map, "已拍到该商品");
    }

    /**
     * 异步生成订单
     * @param uid
     * @param serviceCharge
     * @param balance
     * @param price
     * @param rid
     */
    @Async
    public void delKey(Long uid , BigDecimal serviceCharge , BigDecimal balance , BigDecimal price ,
                       Long  rid){
        //记录
        YxAuctionRecord yxAuctionRecord = yxAuctionRecordMapper.selectById(rid);

        //订单
        YxAuctionOrder yxAuctionOrder = new YxAuctionOrder();
        //入库订单
        yxAuctionOrder.setAuctionRecordId(yxAuctionRecord.getId());
        yxAuctionOrder.setStatus(0);
        //只能提货
        if(1==yxAuctionRecord.getIsMax()){
            yxAuctionOrder.setIsMax(1);
        }
        yxAuctionOrder.setCreateTime(new Date());
        yxAuctionOrder.setPrice(yxAuctionRecord.getPrice());
        yxAuctionOrder.setServiceMoney(yxAuctionRecord.getServiceCharge());
        yxAuctionOrder.setUserId(uid);
        this.save(yxAuctionOrder);

        //塞入redis,过期看是否支付
        Object o = redisUtil.get("dict:pmfksj");
        Integer pm = 60;
        if (ObjectUtil.isNotEmpty(o)) pm = Integer.valueOf(String.valueOf(o));

        String redisKey = String.valueOf(StrUtil.format("{}{}", "auction:unpay:", yxAuctionOrder.getId()));
        redisTemplate.opsForValue().set(redisKey, yxAuctionOrder.getOrderId() , pm, TimeUnit.MINUTES);

        redisUtil.set("auctionOrder" + yxAuctionOrder.getId(), yxAuctionOrder.getId() , 60*60*24*2);

    }

    private void thinkTime(String startTime, String endTime, Integer advanceTime, Integer afterTime , Long uid) {
        //判断是否在抢拍时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");//注意月份是MM
        Date date= null;
        try {
            date = simpleDateFormat.parse(startTime);
        } catch (ParseException e) {
            e.printStackTrace();
            throw new YshopException("时间格式错误");
        }

        Calendar calendar =Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(calendar.SECOND, -afterTime);


        //是否是新人
        /*Integer newPeople = baseMapper.isNewPeople(uid);
        if (newPeople != 0) {
            Object time = redisUtil.get("dict:xrtqjcsj");
            calendar.add(calendar.SECOND , -Integer.valueOf(String.valueOf(time)));
        }*/

        //查看当前用户等级
        if(advanceTime != 0) calendar.add(calendar.SECOND , -advanceTime);

        //当前时间
        Calendar s =Calendar.getInstance();
        s.setTime(new Date());
        //抢拍时间
        Calendar s1 = Calendar.getInstance();
        s1.setTime(new Date());
        s1.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
        s1.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE));
        s1.set(Calendar.SECOND, calendar.get(Calendar.SECOND));
        //判断是否开始 -- 未开始
        if(s.getTime().getTime() < s1.getTime().getTime()){
            throw new YshopException("该抢拍商品未开始");
        }
        String newStartTime = simpleDateFormat.format(calendar.getTime());
        Integer type = RegaxTimeUtil.regaxTime(newStartTime, endTime);
        //还未开始
        if (3 == type) {
            throw new YshopException("该抢拍商品已结束");
        }
    }


    public boolean lock(String key, int value, long releaseTime) {
        key = "lock"+key;
        // 尝试获取锁
        Boolean boo = redisTemplate.opsForValue().setIfAbsent(key, value, releaseTime, TimeUnit.SECONDS);
        // 判断结果
        return boo != null && boo;
    }





    public Boolean lock(String key) throws InterruptedException {
        boolean lock = redisUtil.lock(key);
        if (lock) {
            System.out.println("Successfully got lock - " );
            Thread.sleep(1000);
            redisUtil.delete(key);
        } else {
            System.out.println("Failed to obtain lock - " );
        }
        return lock;
    }
    @Override
    public void addRedis(Long id){
        redisUtil.set("paimai" + id, id);
    }



    @Override
    public ApiResult<Object> oneKeyAuction(YxUser yxUser, String ids, Integer payType, String payPassword, String signatureImg ,HttpServletRequest request) {
        String[] idsArray = ids.split(";");
        BigDecimal totalMoney=new BigDecimal(0);
        BigDecimal totalMoney1=new BigDecimal(0);
//        if(1==payType){
//            throw new YshopException("支付宝暂未开通");
//        }
        YxUserinfo yxUserinfo=yxUserinfoService.selectByUserId(yxUser.getUid());
        if(null==yxUserinfo){
            throw new YshopException("当前账号存在异常，请联系管理员");
        }
        /*if(0==yxUserinfo.getBindWx()){
            throw new YshopException("请先绑定微信账号");
        }
        if(0==yxUserinfo.getBindZfb()){
            throw new YshopException("请先绑定支付宝账号");
        }*/
        List<String> stringList = Arrays.asList(idsArray);
        for (String id:stringList ) {
            YxAuctionOrder yxAuctionOrder=this.baseMapper.selectById(Long.valueOf(id));
            if(null==yxAuctionOrder){
                throw new YshopException("订单为空");
            }
            if(1==yxAuctionOrder.getIsMax()){
                throw new YshopException("该订单已达到最大溢价，只能提货");
            }
            if(2 !=yxAuctionOrder.getStatus()){
                throw new YshopException("该订单状态不为待操作");
            }
            totalMoney=totalMoney.add(yxAuctionOrder.getServiceMoney());
            totalMoney1 = totalMoney1.add(yxAuctionOrder.getPrice());
        }



        //设置新的抢拍单
        for (String id:stringList) {
            YxAuctionOrder yxAuctionOrder=this.baseMapper.selectById(Long.valueOf(id));
            YxAuctionRecord yxAuctionRecord=yxAuctionRecordMapper.selectById(yxAuctionOrder.getAuctionRecordId());

            YxAuctionConfig yxAuctionConfig = yxAuctionConfigMapper.selectById(yxAuctionRecord.getTimeId());

            BigDecimal topPrice=yxAuctionRecord.getTopPrice();
            //获取溢价比例
            YxAppdict yxAppdict=yxAppdictService.findAppdictByCode("yjbl");
            BigDecimal nextPrice =yxAuctionRecord.getPrice().multiply(new BigDecimal(yxAppdict.getMemo())).add(yxAuctionRecord.getPrice());
            YxAuctionRecord newYxAuctionRecord=new YxAuctionRecord();
            BigDecimal topP = nextPrice.multiply(new BigDecimal(yxAppdict.getMemo())).add(nextPrice);
            if(topPrice.compareTo(topP)==-1){
                newYxAuctionRecord.setIsMax(1);
            }
            newYxAuctionRecord.setAuctionProductId(yxAuctionRecord.getAuctionProductId());
            newYxAuctionRecord.setPrice(nextPrice);
            newYxAuctionRecord.setCreateTime(new Date());
            newYxAuctionRecord.setUpId(yxAuctionRecord.getId());
            newYxAuctionRecord.setTopPrice(yxAuctionRecord.getTopPrice());
            YxAppdict sxf=yxAppdictService.findAppdictByCode("sxf");
            if(null !=sxf){
                //赠送的积分
                BigDecimal add = new BigDecimal(sxf.getMemo());
                newYxAuctionRecord.setServiceCharge(nextPrice.multiply(add));
            }else{
                newYxAuctionRecord.setServiceCharge(nextPrice.multiply(new BigDecimal(0.02)));
            }
            newYxAuctionRecord.setFirstCommission(yxAuctionRecord.getFirstCommission());
            newYxAuctionRecord.setSecondCommission(yxAuctionRecord.getSecondCommission());
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");//注意月份是MM
            Calendar  calendar =Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(calendar.DATE,1);
            String startTime = simpleDateFormat.format(calendar.getTime());
            newYxAuctionRecord.setStartTime(startTime);
            newYxAuctionRecord.setTimeId(yxAuctionConfig.getIsVip() == 0? yxAuctionRecord.getTimeId():1);
            newYxAuctionRecord.setUserId(yxUser.getUid());
            if(0==yxAuctionRecord.getParentId()){
                newYxAuctionRecord.setParentId(yxAuctionRecord.getId());
            }else{
                newYxAuctionRecord.setParentId(yxAuctionRecord.getParentId());
            }
            yxAuctionRecordMapper.insert(newYxAuctionRecord);
            redisUtil.set("paimai"+newYxAuctionRecord.getId(),newYxAuctionRecord.getId());
            //修改买单表
            yxAuctionOrder.setSignatureImg(signatureImg);
            yxAuctionOrder.setStatus(AuctionOrderEnum.TYPE_4.getValue());
            yxAuctionOrder.setIsPayService(1);
            yxAuctionOrder.setSellPrice(nextPrice);
            yxAuctionOrder.setReceiveType(AuctionOrderEnum.RECEIVE_1.getValue());
            this.baseMapper.updateById(yxAuctionOrder);
        }
        return ApiResult.ok("转拍成功");
    }

    @Override
    public ApiResult<Object> findTotalMoney(YxUser yxUser, String ids, HttpServletRequest request) {
        String[] idsArray = ids.split(";");
        BigDecimal totalMoney=new BigDecimal(0);
        List<String> stringList = Arrays.asList(idsArray);
        for (String id:stringList
        ) {
            YxAuctionOrder yxAuctionOrder=this.baseMapper.selectById(Long.valueOf(id));
            if(null==yxAuctionOrder){
                throw new YshopException("订单为空");
            }
            if(1==yxAuctionOrder.getIsMax()){
                throw new YshopException("该订单已达到最大溢价，只能提货");
            }
//            if(yxUser.getUid() !=yxAuctionOrder.getUserId()){
//                throw new YshopException("该订单不是当前用户");
//            }
            if(2 !=yxAuctionOrder.getStatus()){
                throw new YshopException("该订单状态不为待操作");
            }
            totalMoney=totalMoney.add(yxAuctionOrder.getServiceMoney());
        }
        return ApiResult.ok(totalMoney);
    }

    @Override
    public ApiResult<Object> getPopUpData(String ids) {
        String[] idsArray = ids.split(";");
        Map<String , Object> m = new HashMap<>();

        BigDecimal totalMoney = BigDecimal.ZERO;
        BigDecimal servicePrice = BigDecimal.ZERO;
        List<String> stringList = Arrays.asList(idsArray);
        for (String id:stringList ) {
            YxAuctionOrder yxAuctionOrder=this.baseMapper.selectById(Long.valueOf(id));
            servicePrice=servicePrice.add(yxAuctionOrder.getServiceMoney());
            totalMoney = totalMoney.add(yxAuctionOrder.getPrice());
        }
        String serviceRatio = String.valueOf(redisUtil.get("dict:sxf"));

        m.put("totalMoney",totalMoney);
        m.put("servicePrice",servicePrice);
        m.put("serviceRatio",serviceRatio);

        return ApiResult.ok(m);
    }

    /**
     * 兑换积分
     *
     * @param uid
     * @param id
     * @return
     */
    @Override
    public ApiResult<Object> creditsExchange(Long uid, Long id) {
        YxAuctionOrder yxAuctionOrder=this.baseMapper.selectById(id);

        YxUser user = userService.getById(uid);

        if(null==yxAuctionOrder){
            throw new YshopException("订单不存在");
        }
        if(2 !=yxAuctionOrder.getStatus()){
            throw new YshopException("订单状态不为待操作");
        }
        YxAuctionRecord auctionRecord = yxAuctionRecordMapper.selectById(yxAuctionOrder.getAuctionRecordId());
        if (yxAuctionOrder.getIsMax() != 1)  throw new YshopException("未达到封顶价，不可兑换银锭！");

        BigDecimal creditsExchangeRatio = new BigDecimal(String.valueOf(redisUtil.get("dict:creditsExchangeRatio")));
        BigDecimal in = yxAuctionOrder.getPrice().multiply(creditsExchangeRatio).setScale(2,BigDecimal.ROUND_HALF_UP);
        BigDecimal balance = user.getIntegral().add(in);
        //金额流水入库
        YxUserBill integralBill = YxUserBill.builder()
                .uid(user.getUid())
                .title("拍品兑换银锭")
                .linkId(yxAuctionOrder.getId().toString())
                .type(BillDetailEnum.TYPE_9.getValue())
                .category(BillDetailEnum.CATEGORY_2.getValue())
                .number(in)
                .balance(balance)
                .mark("拍品兑换银锭")
                .status(BillEnum.STATUS_1.getValue())
                .pm(BillEnum.PM_1.getValue())
                .build();
        yxUserBillService.save(integralBill);
        user.setIntegral(balance);
        userService.updateById(user);

        //修改订单状态
        yxAuctionOrder.setReceiveType(AuctionOrderEnum.RECEIVE_2.getValue());
        yxAuctionOrder.setStatus(AuctionOrderEnum.TYPE_4.getValue());
        this.baseMapper.updateById(yxAuctionOrder);

        return ApiResult.ok("兑换积分成功");
    }

    /**
     * 一键收单
     * @param singleDtoList
     * @param uid
     * @return
     */
    @Override
    public void singleOrder(List<SingleDto> singleDtoList , Long uid){
        singleDtoList.forEach(singleDto -> {
            //抢拍记录
            YxAuctionRecord yxAuctionRecord=yxAuctionRecordMapper.selectById(singleDto.getId());
            //判断是否购买
            if (yxAuctionRecord.getIsBuy() != 1){
                //给商品上锁
                boolean lock = lock("paimai"+yxAuctionRecord.getId(),1,60);
                if(lock){
                    BigDecimal nowPrice = new BigDecimal(String.valueOf(redisUtil.get("UserPrice" + uid)));
                    if (nowPrice.compareTo(yxAuctionRecord.getServiceCharge())  > -1)  {
                        //扣除手续费
                        BigDecimal balance = nowPrice.subtract(yxAuctionRecord.getServiceCharge());
                        YxUserBill userBill = YxUserBill.builder()
                                .uid(uid)
                                .title("手续费支付")
                                .category(BillDetailEnum.CATEGORY_1.getValue())
                                .type(BillDetailEnum.TYPE_11.getValue())
                                .number(yxAuctionRecord.getServiceCharge())
                                .balance(balance)
                                .mark("手续费支付")
                                .status(BillEnum.STATUS_1.getValue())
                                .payType(3)
                                .orderNo("serviceMoney"+ RandonOrderNoUtil.getOrderIdByTime())
                                .pm(BillEnum.PM_0.getValue())
                                .build();
                        yxUserBillService.save(userBill);
                        //塞入扣除redis数据 2秒后修改用户余额
                        redisUtil.set("UserPrice"+uid,balance);
                        baseMapper.updateUserPriceById(uid , balance);

                        //修改拍卖状态
                        yxAuctionRecord.setIsBuy(1);
                        yxAuctionRecordMapper.updateById(yxAuctionRecord);
                        delKey(uid , yxAuctionRecord.getServiceCharge() , BigDecimal.ZERO , yxAuctionRecord.getPrice() , yxAuctionRecord.getId());

                    } else {
                        //删除拍卖锁
                        redisUtil.delete("lockpaimai"+yxAuctionRecord.getId());
                    }
                }
            }
        });
    }


    @Override
    public ApiResult<Object> turnAuction(YxUser yxUser, String id, Integer payType, String payPassword, String signatureImg ,String yjbl,HttpServletRequest request) throws ParseException {
        YxAuctionOrder yxAuctionOrder=this.baseMapper.selectById(Long.valueOf(id));
        if(null==yxAuctionOrder){
            throw new YshopException("订单为空");
        }
        if(1==yxAuctionOrder.getIsMax()){
            throw new YshopException("该订单已达到最大溢价，只能提货");
        }
        YxUserinfo yxUserinfo=yxUserinfoService.selectByUserId(yxUser.getUid());
        if(null==yxUserinfo){
            throw new YshopException("当前账号存在异常，请联系管理员");
        }
        /*if(0==yxUserinfo.getBindWx()){
            throw new YshopException("请先绑定微信账号");
        }
        if(0==yxUserinfo.getBindZfb()){
            throw new YshopException("请先绑定支付宝账号");
        }*/
        if(2 !=yxAuctionOrder.getStatus()){
            throw new YshopException("该订单状态不为待操作");
        }
        YxAuctionRecord yxAuctionRecord=yxAuctionRecordMapper.selectById(yxAuctionOrder.getAuctionRecordId());

        YxAuctionConfig yxAuctionConfig = yxAuctionConfigMapper.selectById(yxAuctionRecord.getTimeId());

        //设置新的抢拍单
        YxAuctionRecord newYxAuctionRecord=new YxAuctionRecord();
        newYxAuctionRecord.setAuctionProductId(yxAuctionRecord.getAuctionProductId());
        //获取溢价比例
        /*YxAppdict yxAppdict=yxAppdictService.findAppdictByCode("yjbl");
        BigDecimal topPrice=yxAuctionRecord.getTopPrice();
        BigDecimal nextPrice =yxAuctionRecord.getPrice().multiply(new BigDecimal(yxAppdict.getMemo())).add(yxAuctionRecord.getPrice());
        BigDecimal topP = nextPrice.multiply(new BigDecimal(yxAppdict.getMemo())).add(nextPrice);
        if(topPrice.compareTo(topP)==-1){
            newYxAuctionRecord.setIsMax(1);
        }*/

        BigDecimal nextPrice = BigDecimal.ZERO;
        if(yjbl.indexOf("-")>=0){
            nextPrice = yxAuctionRecord.getPrice().subtract(yxAuctionRecord.getPrice().multiply(new BigDecimal(yjbl.substring(yjbl.indexOf("-")+1,yjbl.length()))));
        }else{
            nextPrice =yxAuctionRecord.getPrice().multiply(new BigDecimal(yjbl)).add(yxAuctionRecord.getPrice());
        }
        BigDecimal topPrice=yxAuctionRecord.getTopPrice();
        if(topPrice.compareTo(nextPrice)==-1){
            newYxAuctionRecord.setIsMax(1);
        }
        newYxAuctionRecord.setPrice(nextPrice);
        newYxAuctionRecord.setCreateTime(new Date());
        newYxAuctionRecord.setTopPrice(yxAuctionRecord.getTopPrice());
        YxAppdict sxf=yxAppdictService.findAppdictByCode("sxf");
        if(null !=sxf){
            //赠送的积分
            BigDecimal add = new BigDecimal(sxf.getMemo());
            newYxAuctionRecord.setServiceCharge(nextPrice.multiply(add));
        }else{
            newYxAuctionRecord.setServiceCharge(nextPrice.multiply(new BigDecimal(0.02)));
        }
        newYxAuctionRecord.setFirstCommission(yxAuctionRecord.getFirstCommission());
        newYxAuctionRecord.setSecondCommission(yxAuctionRecord.getSecondCommission());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");//注意月份是MM
        Calendar  calendar =Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(calendar.DATE,1);
        String startTime = simpleDateFormat.format(calendar.getTime());
        newYxAuctionRecord.setStartTime(startTime);
        newYxAuctionRecord.setUpId(yxAuctionRecord.getId());
        newYxAuctionRecord.setTimeId(yxAuctionConfig.getIsVip() == 1 ? 1:yxAuctionRecord.getTimeId());
        newYxAuctionRecord.setUserId(yxUser.getUid());
        if(0==yxAuctionRecord.getParentId()){
            newYxAuctionRecord.setParentId(yxAuctionRecord.getId());
        }else{
            newYxAuctionRecord.setParentId(yxAuctionRecord.getParentId());
        }
        yxAuctionRecordMapper.insert(newYxAuctionRecord);
        redisUtil.set("paimai"+newYxAuctionRecord.getId(),newYxAuctionRecord.getId());
        //修改买单表

        yxAuctionOrder.setSignatureImg(signatureImg);
        yxAuctionOrder.setStatus(AuctionOrderEnum.TYPE_4.getValue());
        yxAuctionOrder.setSellPrice(nextPrice);
        yxAuctionOrder.setIsPayService(1);
        yxAuctionOrder.setReceiveType(AuctionOrderEnum.RECEIVE_1.getValue());
        this.baseMapper.updateById(yxAuctionOrder);

        return ApiResult.ok("转拍成功");
    }

    @Override
    public ApiResult<YxAuctionOrderConfirm> confirmOrder(Long uid, Long id) {
        YxAuctionOrderConfirm yxAuctionOrderConfirm=this.baseMapper.confirmOrder(uid,id);
        if(null==yxAuctionOrderConfirm){
            throw new YshopException("订单不存在");
        }
        yxAuctionOrderConfirm.setYxUserAddress(yxUserAddressMapper.selectIsDefaultAddress(uid));
        return ApiResult.ok(yxAuctionOrderConfirm);
    }

    @Override
    public ApiResult<Object> confirm(Long uid, Long id, Long userAddressId) {
        YxAuctionOrder yxAuctionOrder=this.baseMapper.selectById(id);
        if(null==yxAuctionOrder){
            throw new YshopException("订单不存在");
        }
        if(2 !=yxAuctionOrder.getStatus()){
            throw new YshopException("订单状态不为待操作");
        }

        YxUserAddress yxUserAddress=yxUserAddressMapper.selectById(userAddressId);
        if(null==yxUserAddress){
            throw new YshopException("地址id有误");
        }

        BigDecimal creditsExchangeRatio = new BigDecimal(String.valueOf(redisUtil.get("dict:creditsExchangeRatio")));
        BigDecimal in = yxAuctionOrder.getPrice().multiply(creditsExchangeRatio).setScale(2,BigDecimal.ROUND_HALF_UP);
        YxUser user = userService.getById(uid);
        BigDecimal balance = user.getIntegral().add(in);
        //金额流水入库
        YxUserBill integralBill = YxUserBill.builder()
                .uid(user.getUid())
                .title("提货赠送银锭")
                .linkId(yxAuctionOrder.getId().toString())
                .type(BillDetailEnum.TYPE_9.getValue())
                .category(BillDetailEnum.CATEGORY_2.getValue())
                .number(in)
                .balance(balance)
                .mark("提货赠送银锭")
                .status(BillEnum.STATUS_1.getValue())
                .pm(BillEnum.PM_1.getValue())
                .build();
        yxUserBillService.save(integralBill);
        user.setIntegral(balance);
        userService.updateById(user);

        //修改订单状态
        yxAuctionOrder.setReceiveType(AuctionOrderEnum.RECEIVE_2.getValue());
        yxAuctionOrder.setStatus(AuctionOrderEnum.TYPE_6.getValue());
        yxAuctionOrder.setUserName(yxUserAddress.getRealName());
        yxAuctionOrder.setUserPhone(yxUserAddress.getPhone());
        yxAuctionOrder.setUserAddress(yxUserAddress.getProvince()+yxUserAddress.getCity()+yxUserAddress.getDistrict()+yxUserAddress.getDetail());
        this.baseMapper.updateById(yxAuctionOrder);

        return ApiResult.ok("发起提货成功");
    }

    @Override
    public ApiResult<Page<YxAuctionOrderList>> productOrderPage(Long uid,Integer type, int page, int limit) {
        Page page1=new Page(page,limit);
        Page<YxAuctionOrderList> paList=new Page<>();
        if(3==type){
            paList=this.baseMapper.productOrder1Page(page1,uid,type);
        }else{
            paList=this.baseMapper.productOrderPage(page1,uid,type);
        }
        return ApiResult.ok(paList);
    }

    @Override
    public ApiResult<Page<YxAuctionOrderList>> productHistoryOrderPage(Long uid, Integer type, int page, int limit) {
        Page page1=new Page(page,limit);
        Page<YxAuctionOrderList> paList=this.baseMapper.productHistoryOrderPage(page1,uid,type);
        return ApiResult.ok(paList);
    }

    @Override
    public ApiResult<YxAuctionRecordDto> findAuctionOrderDetail(Long uid, Long id) {
        YxAuctionOrder yxAuctionOrder=this.baseMapper.selectById(id);
        if(null==yxAuctionOrder){
            throw new YshopException("订单不存在");
        }
        YxAuctionRecordDto yxAuctionRecordDto=yxAuctionRecordMapper.getYxAuctionProductDetail(yxAuctionOrder.getAuctionRecordId());
        if(null !=yxAuctionRecordDto){
            //买家信息
            YxUser user =userMapper.selectById(uid);
            SimpleDateFormat strDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if(ObjectUtil.isNotEmpty(yxAuctionOrder.getPayTime())){
                yxAuctionRecordDto.setPayTime(strDateFormat.format(yxAuctionOrder.getPayTime()));
            }
            if(null != user){
                yxAuctionRecordDto.setMyPhone(user.getPhone());
                yxAuctionRecordDto.setMyNickName(user.getNickname());
                YxAuthentication yxAuthentication=yxAuthenticationMapper.selectByUid(user.getUid());
                if(null !=yxAuthentication && 1==yxAuthentication.getStatus()){
                    yxAuctionRecordDto.setMyRealName(yxAuthentication.getRealName());
                }
            }

            //卖家基本信息
            YxUser yxUser=userMapper.selectById(yxAuctionRecordDto.getUserId());
            if(null !=yxUser){
                yxAuctionRecordDto.setPhone(yxUser.getPhone());
                YxAuthentication yxAuthentication=yxAuthenticationMapper.selectByUid(yxUser.getUid());
                if(null !=yxAuthentication && 1==yxAuthentication.getStatus()){
                    yxAuctionRecordDto.setRealName(yxAuthentication.getRealName());
                }
                yxAuctionRecordDto.setNickname(yxUser.getNickname());

                //账户收款码
                YxUserinfo userinfo = yxUserinfoService.getOne(new QueryWrapper<YxUserinfo>().lambda().eq(YxUserinfo::getUid, yxUser.getUid()));
                if(ObjectUtil.isNotEmpty(userinfo)){
//                    if(yxAuctionRecordDto.getPayType() == 1){
                        yxAuctionRecordDto.setBindZfb(userinfo.getBindZfb());
                        yxAuctionRecordDto.setZhifubaoName(userinfo.getZhifubaoName());
                        yxAuctionRecordDto.setZhifubaoCode(userinfo.getZhifubaoCode());
//                    }else if(yxAuctionRecordDto.getPayType() == 2){
                        yxAuctionRecordDto.setBindWx(userinfo.getBindWx());
                        yxAuctionRecordDto.setWeixinName(userinfo.getWeixinName());
                        yxAuctionRecordDto.setWeixinCode(userinfo.getWeixinCode());
//                    }else {
                        YxUserBank one = userBankService.getOne(new QueryWrapper<YxUserBank>().lambda().eq(YxUserBank::getUid, userinfo.getUid()));
                        if(ObjectUtil.isNotEmpty(one)){
                            yxAuctionRecordDto.setBindBank(1);
                            yxAuctionRecordDto.setBankName(one.getBankName());
                            yxAuctionRecordDto.setBankNum(one.getBankNumber());
                            yxAuctionRecordDto.setBankRealName(one.getRealName());
                            yxAuctionRecordDto.setBankCode(one.getBankCode());
                        }
//                    }

                }
            }else {
                if (ObjectUtil.isEmpty(yxAuctionRecordDto.getPayId())){
                    yxAuctionRecordDto.setPhone(yxAppdictService.findAppdictByCode("wxzh").getMemo());
                    yxAuctionRecordDto.setNickname("漫步人生路");
                    yxAuctionRecordDto.setRealName("漫步人生路");
                    yxAuctionRecordDto.setBindZfb(1);
                    yxAuctionRecordDto.setZhifubaoName(yxAppdictService.findAppdictByCode("zfbm").getMemo());
                    yxAuctionRecordDto.setZhifubaoCode(yxAppdictService.findAppdictByCode("zfbcode").getMemo());
                    yxAuctionRecordDto.setBindWx(1);
                    yxAuctionRecordDto.setWeixinName(yxAppdictService.findAppdictByCode("wxm").getMemo());
                    yxAuctionRecordDto.setWeixinCode(yxAppdictService.findAppdictByCode("wxcode").getMemo());
                    yxAuctionRecordDto.setBindBank(1);
                    yxAuctionRecordDto.setBankName(yxAppdictService.findAppdictByCode("yhkhh").getMemo());
                    yxAuctionRecordDto.setBankNum(yxAppdictService.findAppdictByCode("yhkh").getMemo());
                    yxAuctionRecordDto.setBankRealName(yxAppdictService.findAppdictByCode("yhzsxm").getMemo());
                    yxAuctionRecordDto.setBankCode(yxAppdictService.findAppdictByCode("yhtp").getMemo());
                } else {
                    YxTerracePayInfo terracePayInfo = terracePayInfoService.getById(yxAuctionRecordDto.getPayId());
                    yxAuctionRecordDto.setPhone(terracePayInfo.getPhone());
                    yxAuctionRecordDto.setNickname(terracePayInfo.getName());
                    yxAuctionRecordDto.setRealName(terracePayInfo.getName());
                    yxAuctionRecordDto.setBindZfb(1);
                    yxAuctionRecordDto.setZhifubaoName(terracePayInfo.getZfbName());
                    yxAuctionRecordDto.setZhifubaoCode(terracePayInfo.getZfbCode());
                    yxAuctionRecordDto.setBindWx(1);
                    yxAuctionRecordDto.setWeixinName(terracePayInfo.getWxName());
                    yxAuctionRecordDto.setWeixinCode(terracePayInfo.getWxCode());
                    yxAuctionRecordDto.setBindBank(1);
                    yxAuctionRecordDto.setBankName(terracePayInfo.getYhkhh());
                    yxAuctionRecordDto.setBankNum(terracePayInfo.getYhkh());
                    yxAuctionRecordDto.setBankRealName(terracePayInfo.getYhzsxm());
                    yxAuctionRecordDto.setBankCode(terracePayInfo.getYhtp());
                }
            }
            yxAuctionRecordDto.setYxAuctionProductDto(yxAuctionProductService.getOne(
                    new QueryWrapper<YxAuctionProduct>().lambda()
                            .eq(YxAuctionProduct::getId,yxAuctionRecordDto.getAuctionProductId())));
            yxAuctionRecordDto.setYxAuctionOrder(yxAuctionOrder);
            if(0==yxAuctionOrder.getStatus()){
                YxAppdict dict = yxAppdictService.findAppdictByCode("pmfksj");
                Integer time = Integer.valueOf(dict.getMemo())*60000;
                yxAuctionRecordDto.setTimes(yxAuctionOrder.getCreateTime().getTime()+time-System.currentTimeMillis());
            }
        }
        return ApiResult.ok(yxAuctionRecordDto);
    }

    @Override
    public YxAuctionOrder selectByAuctionRecord(Long id) {
        return this.baseMapper.selectByAuctionRecord(id);
    }
}
